package jwt

import (
	"context"
	"encoding/json"
	// "fmt"
	"strconv"

	"github.com/golang-jwt/jwt/v4"
	// "github.com/sirupsen/logrus"
	"github.com/zeromicro/go-zero/core/logx"
)

const ( // #24.09.20# 完成
	ANONYMOUS    string = "ANONYMOUS"
	CERTIFICATED string = "CERTIFICATED"
	SUSPENDED    string = "SUSPENDED"
	BANNED       string = "BANNED"
	CANCELLED    string = "CANCELLED"
)

// Option describes the jwt extra data
type Option struct { // #24.07.09# 完成
	Key string
	Val any
}

// WithOption returns the option from k/v
func WithOption(key string, val any) Option { // #24.07.09# 完成
	return Option{
		Key: key,
		Val: val,
	}
}

// NewJwtToken returns the jwt token from the given data.
func NewJwtToken(secretKey string, iat int64, seconds int64, opt ...Option) (string, error) { // #24.07.09# 完成
	claims := make(jwt.MapClaims)
	claims["exp"] = iat + seconds
	claims["iat"] = iat

	for _, v := range opt {
		claims[v.Key] = v.Val
	}

	token := jwt.New(jwt.SigningMethodHS256)
	token.Claims = claims

	return token.SignedString([]byte(secretKey))
}

func GetUserId(ctx context.Context) uint64 { // #24.07.09# 完成
	var userId uint64
	// logrus.Info(fmt.Sprintf("GetUserId: %+T : %+v", ctx.Value("userId"), ctx.Value("userId")))
	if uid, ok := ctx.Value("userId").(string); ok {
		if id, err := strconv.ParseInt(uid, 10, 64); err == nil && id > 0 {
			userId = uint64(id)
		} else {
			logx.Errorw("GetUserId err", logx.Field("detail", err.Error()))
		}
	}

	return userId
}

func GetSecurityStatus(ctx context.Context) string { // #24.09.21# 完成
	var securityStatus string
	if status, ok := ctx.Value("securityStatus").(string); ok {
		securityStatus = status
	}

	return securityStatus
}

func GetBackendUserId(ctx context.Context) uint64 { // #24.06.19# 完成
	var userId uint64
	if val := ctx.Value("userId"); val != nil {
		if uid, err := val.(json.Number).Int64(); err == nil {
			userId = uint64(uid)
		} else {
			logx.Errorw("GetBackendUserId error", logx.Field("detail", err.Error()))
		}
	}

	return userId
}
